package itsm.isperp.module.service.task;

import itsm.isperp.framework.core.context.ContextHolder;
import itsm.isperp.framework.data.dialect.DialectFactory;
import itsm.isperp.framework.service.BaseService;
import itsm.isperp.framework.utils.HibernateUUIDGenerator;
import itsm.isperp.framework.web.request.JqGridFilterRuleOp;
import itsm.isperp.framework.web.request.JqGridRequest;
import itsm.isperp.module.entity.app.AppCalendarDay;
import itsm.isperp.module.entity.task.TskInspectCiPlan;
import itsm.isperp.module.entity.task.TskPlanTask;
import itsm.isperp.module.entity.task.TskPlantaskTodoMq;
import itsm.isperp.module.entity.task.TskTask;
import itsm.isperp.module.repository.app.AppCalendarDayMapper;
import itsm.isperp.module.repository.task.TskPlanTaskMapper;
import itsm.isperp.module.repository.task.TskPlantaskTodoMqMapper;
import itsm.isperp.module.repository.task.TskTaskMapper;
import itsm.isperp.workflow.service.BpmProcessRunService;

import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jdbc.support.DatabaseType;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

@Service
public class TskPlanTaskService extends BaseService<TskPlanTask> {

	@Autowired
	protected TskPlanTaskMapper tskPlanTaskMapper;

	@Autowired
	protected TskTaskMapper tskTaskMapper;

	@Autowired
	protected TskTaskService tskTaskService;

	@Autowired
	protected AppCalendarDayMapper appCalendarDayMapper;

	@Autowired
	protected TskPlantaskTodoMqService tskPlantaskTodoMqService;

	@Autowired
	protected TskPlantaskTodoMqMapper tskPlantaskTodoMqMapper;

	@Autowired
	BpmProcessRunService bpmProcessRunService;

	@Autowired
	protected TskInspectCiPlanService tskInspectCiPlanService;

	@Override
	public TskPlanTaskMapper getRepository() {
		return this.tskPlanTaskMapper;
	}

	public static final String getProcessKey() {
		return "taskProcess";
	}

	public void deleteByProjectId(String projectId) {
		getRepository().deleteByProjectId(projectId);
	}

	/**
	 * 根据项目制定的计划自动生成任务
	 * 
	 * @throws SQLException
	 */
	public boolean generateTask() throws SQLException {
		// 1、获取计划任务列表，计划任务必须满足的条件：其所属的项目状态已审批通过，而且还没有关闭
		JqGridRequest req = new JqGridRequest();
		req.addFilterRule("status", JqGridFilterRuleOp.eq, "0"); //
		req.addFilterRule("projectId", JqGridFilterRuleOp.in,
				"(SELECT id FROM proj_project WHERE stage='已发布')");// 已发布的项目
		List<TskPlanTask> tskPlanTasks = this.tskPlanTaskMapper
				.findAllPlanTask(req);

		for (TskPlanTask tskPlanTask : tskPlanTasks) {
			// 先判断是否生成任务，然后在生成任务，分两种情况，一次性任务和周期性任务
			int intGenerateTask = tskPlanTaskMapper.isCreatetask(tskPlanTask
					.getId());
			// 生成任务(1:正常生成的任务，10：非工作日要生成的任务，100：顺延生成的任务)
			if (intGenerateTask == 1 || intGenerateTask == 10
					|| intGenerateTask == 100) {
				TskTask tskTask = generateTaskByPlanTask(tskPlanTask);
				tskTaskService.saveOrUpdate(tskTask);

				List<TskInspectCiPlan> cps = tskInspectCiPlanService
						.findByPlanId(tskPlanTask.getId());

				if (cps.size() > 0) {
					List<Object[]> args = new ArrayList<>();
					for (TskInspectCiPlan cp : cps) {
						Object[] arg = new Object[5];
						arg[0] = HibernateUUIDGenerator.generate();
						arg[1] = cp.getCiId();
						arg[2] = tskTask.getId();
						arg[3] = tskTask.getPlanTaskId();
						arg[4] = cp.getOrderNum();
						args.add(arg);
					}

					JdbcTemplate jdbcTemplate = ContextHolder
							.getSpringBean("jdbcTemplate");

					String sql = "INSERT INTO tsk_inspect_ci_info(id,ci_id,task_id,plan_id,order_num) VALUES(?,?,?,?,?);";
					if (args.size() > 0) {

						jdbcTemplate.batchUpdate(sql, args);
					}

				}

				tskTask.getId();

				// 启动流程
				bpmProcessRunService.startProcess("admin", getProcessKey(),
						tskTask.getId(), null);

				// 更新顺延队列
				if (intGenerateTask == 100) {
					tskPlantaskTodoMqMapper
							.updateTskPlantaskTodoMqStatus(tskTask.getId());
				}
			} else if (intGenerateTask == -1) {// 不生成，顺延
				// 保存顺延信息
				saveDelayInfo(tskPlanTask);

			} else {// 不生成
				// 写入日志信息
			}

		}
		// 更新计划任务状态，对于一次性任务，如果当前时间>计划任务的开始时间，则默认任务已经生成，并将状态值为1，
		// 对于周期性任务，如果当前时间大于执行周期的结束时间，则默认周期任务不再生成，并将状态置为1
		if (DialectFactory.getDatabaseType() == DatabaseType.MYSQL)
			tskPlanTaskMapper.updatePlanTaskStatus("sysdate()");
		else
			tskPlanTaskMapper.updatePlanTaskStatus("sysdate");

		return true;
	}

	/**
	 * 根据计划任务生成任务
	 * 
	 * @param TskPlanTask
	 * @return
	 */
	private TskTask generateTaskByPlanTask(TskPlanTask tskPlanTask) {
		TskTask tskTask = new TskTask();
		tskTask.setTaskType(tskPlanTask.getTaskType());
		tskTask.setName(tskPlanTask.getTaskName());
		tskTask.setPlanTaskId(tskPlanTask.getId());
		tskTask.setProjectId(tskPlanTask.getProjectId());
		tskTask.setProjectStage(tskPlanTask.getProjectStage());
		tskTask.setContent(tskPlanTask.getTaskContent());
		tskTask.setTarget(tskPlanTask.getTaskTarget());
		tskTask.setDeliverables(tskPlanTask.getTaskDeliverables());
		tskTask.setPriority(tskPlanTask.getTaskPriority());
		tskTask.setPlanTimes(tskPlanTask.getPlanTimes());
		tskTask.setPlanPrincipalId(tskPlanTask.getTaskPrincipalId());
		tskTask.setPlanPrincipalName(tskPlanTask.getTaskPrincipalName());

		tskTask.setInspectTemplateDefId(tskPlanTask.getInspectTemplateDefId());
		// 计划开始时间，计划结束时间
		if (tskPlanTask.getExcuteType().equalsIgnoreCase("ONETIME")) {
			if (tskPlanTask.getExcuteOnePlanStartTime() != null) {
				tskTask.setPlanStartTime(tskPlanTask
						.getExcuteOnePlanStartTime());
			}
			if (tskPlanTask.getExcuteOnePlanEndTime() != null) {
				tskTask.setPlanEndTime(tskPlanTask.getExcuteOnePlanEndTime());
			}
		} else {
			// 周期性任务的时间等于当天日期+时间组合
			DateTime tmpDt = DateTime.now().plusDays(
					tskPlanTask.getReleaseBeforeDays());

			if (tskPlanTask.getExcuteTimeStart() != null) {
				Calendar calendarExcuteTimeStart = Calendar.getInstance();

				calendarExcuteTimeStart.setTime(tskPlanTask
						.getExcuteTimeStart());

				DateTime dtS = new DateTime(tmpDt.getYear(),
						tmpDt.getMonthOfYear(), tmpDt.getDayOfMonth(),
						calendarExcuteTimeStart.get(Calendar.HOUR_OF_DAY),
						calendarExcuteTimeStart.get(Calendar.MINUTE));

				tskTask.setPlanStartTime(new Timestamp(dtS.toDate().getTime()));

			}

			if (tskPlanTask.getExcuteTimeEnd() != null) {

				Calendar calendarExcuteTimeEnd = Calendar.getInstance();
				calendarExcuteTimeEnd.setTime(tskPlanTask.getExcuteTimeEnd());

				DateTime dtE = new DateTime(tmpDt.getYear(),
						tmpDt.getMonthOfYear(), tmpDt.getDayOfMonth(),
						calendarExcuteTimeEnd.get(Calendar.HOUR_OF_DAY),
						calendarExcuteTimeEnd.get(Calendar.MINUTE));
				tskTask.setPlanEndTime(new Timestamp(dtE.toDate().getTime()));

			}

		}
		return tskTask;
	}

	/**
	 * 当任务需要顺延是，保存任务顺延信息
	 * 
	 * @param TskPlanTask
	 */
	private void saveDelayInfo(TskPlanTask tskPlanTask) {
		TskPlantaskTodoMq tskPlantaskTodo = new TskPlantaskTodoMq();
		DateTime dt = DateTime.now().plusDays(
				tskPlanTask.getReleaseBeforeDays());
		tskPlantaskTodo.setTaskDate(dt.toDate());
		tskPlantaskTodo.setTaskId(tskPlanTask.getId());
		tskPlantaskTodo.setStatus(0);

		AppCalendarDay appCalendarDay = appCalendarDayMapper.getFirstWorkdate(
				dt.toDate(), tskPlanTask.getProjectId());
		if (appCalendarDay != null && appCalendarDay.getCalendarDate() != null) {
			tskPlantaskTodo.setFirstWorkDate(appCalendarDay.getCalendarDate());
		}
		tskPlantaskTodoMqService.saveOrUpdate(tskPlantaskTodo);

	}

}
